<?php
namespace TwinPeaks\Stdlib;
use TwinPeaks\Core as Core;

class CCache extends Core\CStdlib
{
	use Core\TMultiton;
	
	static private $backendServiceId = 1;
	private $backendHandle;

	private $storageEngine;
	
	/**
	 * @return
	 */
	final function getStorage()
	{
		if (isset($this->storageEngine))
			return $this->storageEngine;

		$self = Core\get_class_method_name(__METHOD__);
		if ($this->hasDecoration($self))
		{
			$engine = $this->renderDecoration($self);
			$this->checkInterface($engine, self::KV_STORAGE_INTERFACE);
		}
		else // Use default filesystem storage
		{
			$this->getApplication()->loadClassByName('@F/lib/storage/kv/', 'CFilesystem');
			$this->storageEngine = new Storage\KeyValue\CFilesystem(self::getDataBaseDir(),
				self::getTokenName() . '_');

			return $this->storageEngine;
		}
	}	
	
	/**
	 * 
	 */
	function getBackendServiceID()
	{
		return 1;
	}
	
	/**
	 * 
	 */
	private function selectNode($key)
	{
		$nodes = $this->service->getNodes();
		$index = Core\numeric_hash($key, count($nodes));
		return $nodes[$index];
	}

	/**
	 * 
	 */
	final protected function onCreate()
	{
		$args = func_get_args();
		if (count($args))
		{
			$this->backendHandle = CService::connect(self::$backendServiceId, $dsn);
		}
		else
		{
			$nodes = self::$appInstance->getNodesByServiceID(self::$backendServiceId);
			$randIndex = mt_rand(0, count($nodes) - 1);
			$this->backendHandle = $nodes[$randIndex]->getServiceByID(self::$backendServiceId)
				->connect();
		}
	}
	
	/**
	 * @return mixed
	 */
	function get($key)
	{
		return $this->getStorage()->get($key);
	}
	
	/**
	 * @return void
	 */
	function set($key, $value)
	{
		$this->getStorage()->set($key, $value);
	}
	
	/**
	 * @return void 
	 */
	function flush()
	{
		foreach ($this->service->getNodes() as $node)
			$node->flush();
	}
}
